#ifndef FIFO_HPP
#define FIFO_HPP
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <iostream>
using namespace std;
#include <string.h>
#include <cerrno>
#include <fcntl.h>
#include <cassert>

#define MODE 0666//创建的管道文件的权限
#define PATH "./fifo"

//控制管道的创建与销毁
class Fifo
{
public:
    Fifo(const char* path)
        :_path(path)
    {
        umask(0);//将权限掩码设置为0

        int n = mkfifo(_path.c_str(), MODE);
        if(n == 0)
        {
            cout << "mkfifo success!!!" << endl;
        }
        else
        {
            cout << "mkfifo error , errno : " << errno << " string errno : " << strerror(errno) << endl;
        }
    }

    ~Fifo()
    {
        int n = unlink(_path.c_str());
        if(n == 0)
        {
            cout << "unlink success!!!" << endl;
        }
        else
        {
            cout << "unlink error , errno : " << errno << " string errno : " << strerror(errno) << endl;
        }
    }

private:
    string _path;
};

//共享内存同步机制实现
//只用起来控制同步，不需要将文件fd暴露给外界
class Sync
{
public:
    Sync()//读写端文件描述符，通过接口打开并赋值
        :_rfd(-1)
        ,_wfd(-1)
    {}

    void OpenReadOrDie()
    {
        int rfd = open(PATH, O_RDONLY);
        if(rfd < 0)
        {
            cout << "read open error , errno : " << errno << " string errno : " << strerror(errno) << endl;
            exit(1);//打开失败直接退出
        }

        _rfd = rfd;
    }

    void OpenWriteOrDie()
    {
        int wfd = open(PATH, O_WRONLY);
        if(wfd < 0)
        {
            cout << "write open error , errno : " << errno << " string errno : " << strerror(errno) << endl;
            exit(1);
        }

        _wfd = wfd;
    }

    bool Wait()
    {
        int signal = 0;
        int n = read(_rfd, &signal, sizeof(signal));
        if(n == sizeof(signal))
        {
            cout << "read success!!!" << endl;
        }
        else if(n == 0)//读端关闭
        {
            cout << "write quit , me too!!!" << endl;
            return false;
        }
        else
        {
            cout << "read error , errno : " << errno << " string error : " << strerror(errno) << endl;
            return false;
        }

        return true;//控制是否共享内存是否还进行通信
    }

    //bool Wakerup
    void Wakeup()
    {
        int signal = 1;
        size_t n = write(_wfd, &signal, sizeof(signal));//原为int
        //cout << "n : " << n << " sizeof(signal) : " << sizeof(signal) << endl;
        assert(n == sizeof(signal));//assert(expression); expression为真程序继续，否则断言报错
    }

    ~Sync()
    {}
private:
    int _rfd;
    int _wfd;
};
#endif